[POWERPC] Merge in outstanding changes from xenppc-unstable.hg.
authorHollis Blanchard <hollisb@us.ibm.com>
Tue, 12 Dec 2006 15:56:06 +0000 (09:56 -0600)
committerHollis Blanchard <hollisb@us.ibm.com>
Tue, 12 Dec 2006 15:56:06 +0000 (09:56 -0600)
It's a long story, but basically a small divergence in xenppc-unstable meant a
large number of changesets couldn't be directly imported to xen-unstable, so
this changeset includes all of them.
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
37 files changed:
config/powerpc64.mk
extras/mini-os/arch/x86/setup.c [changed mode: 0644->0755]
tools/libaio/src/syscall-ppc.h [changed mode: 0755->0644]
tools/libxc/powerpc64/flatdevtree.c
tools/libxc/powerpc64/flatdevtree.h
tools/libxc/powerpc64/utils.c
tools/libxc/powerpc64/xc_linux_build.c
tools/libxc/powerpc64/xc_prose_build.c
tools/libxc/xenctrl.h
tools/libxc/xenguest.h
tools/python/xen/lowlevel/xc/xc.c
tools/python/xen/xend/FlatDeviceTree.py
tools/python/xen/xend/image.py
xen/arch/powerpc/Makefile
xen/arch/powerpc/domain.c
xen/arch/powerpc/memory.c
xen/arch/powerpc/mm.c
xen/arch/powerpc/numa.c [new file with mode: 0644]
xen/arch/powerpc/ofd_fixup_memory.c
xen/arch/powerpc/papr/xlate.c
xen/arch/powerpc/powerpc64/ppc970.c
xen/arch/powerpc/setup.c
xen/arch/powerpc/shadow.c
xen/arch/powerpc/smpboot.c [new file with mode: 0644]
xen/arch/powerpc/usercopy.c
xen/common/Makefile
xen/common/xencomm.c [new file with mode: 0644]
xen/include/asm-powerpc/acpi.h [new file with mode: 0644]
xen/include/asm-powerpc/config.h
xen/include/asm-powerpc/domain.h
xen/include/asm-powerpc/guest_access.h
xen/include/asm-powerpc/mm.h
xen/include/asm-powerpc/numa.h [new file with mode: 0644]
xen/include/asm-powerpc/page.h
xen/include/asm-powerpc/smp.h
xen/include/asm-powerpc/spinlock.h
xen/include/xen/xencomm.h [new file with mode: 0644]

index 9773b24a6c9b2a10fdd39f45a6e69f1ca1f69d0a..cba68fec19f220b7e115e5037e43df43eb675eeb 100644 (file)
@@ -1,5 +1,7 @@
 CONFIG_POWERPC := y
 CONFIG_POWERPC_$(XEN_OS) := y
 
+CONFIG_XENCOMM := y
+
 CFLAGS += -DELFSIZE=64
 LIBDIR := lib
old mode 100644 (file)
new mode 100755 (executable)
old mode 100755 (executable)
new mode 100644 (file)
index 4e9fa2fcdec564814e04e06ac693b9e011f04b5b..f7a44bad7f4e8a38ab8062792d05f572f6eff51b 100644 (file)
@@ -220,6 +220,29 @@ void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size)
        cxt->p_anchor = cxt->pres + 16; /* over the terminator */
 }
 
+int ft_set_rsvmap(void *bphp, int m, u64 physaddr, u64 size)
+{
+       const struct boot_param_header *bph = bphp;
+       u64 *p_rsvmap = (u64 *)
+               ((char *)bph + be32_to_cpu(bph->off_mem_rsvmap));
+       u32 i;
+
+       for (i = 0;; i++) {
+               u64 addr, sz;
+
+               addr = be64_to_cpu(p_rsvmap[i * 2]);
+               sz = be64_to_cpu(p_rsvmap[i * 2 + 1]);
+               if (addr == 0 && size == 0)
+                       break;
+               if (m == i) {
+                       p_rsvmap[i * 2] = cpu_to_be64(physaddr);
+                       p_rsvmap[i * 2 + 1] = cpu_to_be64(size);
+                       return 0;
+               }
+       }
+       return -1;
+}
+
 void ft_begin_tree(struct ft_cxt *cxt)
 {
        cxt->p_begin = cxt->p_anchor;
index d8432dbb6ff3d471c76b4632f608dad78383e44b..794bcd4f78ba758ba91060a1b6b228e7134bd931 100644 (file)
@@ -66,6 +66,7 @@ void ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str);
 void ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val);
 void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size);
 void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size);
+int ft_set_rsvmap(void *bphp, int m, u64 physaddr, u64 size);
 
 void ft_dump_blob(const void *bphp);
 void ft_backtrack_node(struct ft_cxt *cxt);
index 9835f108918cb41287a0e6028b5966cbd4ccaa78..c9d2a31d119fc1a5a4e6ae70442bfe4128570fcc 100644 (file)
@@ -77,7 +77,7 @@ int get_rma_page_array(int xc_handle, int domid, xen_pfn_t **page_array,
     /* We know that the RMA is machine contiguous so lets just get the
      * first MFN and fill the rest in ourselves */
     rc = xc_get_pfn_list(xc_handle, domid, *page_array, 1);
-    if (rc != 1) {
+    if (rc == -1) {
         perror("Could not get the page frame list");
         return -1;
     }
index b2cebb5eef833a276dd6dca4c201c8675a4c9e3c..dc15336556bd3ae9b217bc84d4126f91f5ad9b89 100644 (file)
@@ -89,7 +89,7 @@ static int load_devtree(
     start_info_t *start_info __attribute__((unused)),
     unsigned long start_info_addr)
 {
-    uint32_t start_info[4] = {0, start_info_addr, 0, 0x1000};
+    uint32_t si[4] = {0, start_info_addr, 0, 0x1000};
     struct boot_param_header *header;
     void *chosen;
     void *xen;
@@ -127,8 +127,14 @@ static int load_devtree(
         return rc;
     }
 
+    rc = ft_set_rsvmap(devtree, 1, initrd_base, initrd_len);
+    if (rc < 0) {
+        DPRINTF("couldn't set initrd reservation\n");
+        return ~0UL;
+    }
+
     /* start-info (XXX being removed soon) */
-    rc = ft_set_prop(&devtree, xen, "start-info", start_info, sizeof(start_info));
+    rc = ft_set_prop(&devtree, xen, "start-info", si, sizeof(si));
     if (rc < 0) {
         DPRINTF("couldn't set /xen/start-info\n");
         return rc;
@@ -136,6 +142,15 @@ static int load_devtree(
 
     header = devtree;
     devtree_size = header->totalsize;
+    {
+        static const char dtb[] = "/tmp/xc_domU.dtb";
+        int dfd = creat(dtb, 0666);
+        if (dfd != -1) {
+            write(dfd, devtree, devtree_size);
+            close(dfd);
+        } else
+            DPRINTF("could not open(\"%s\")\n", dtb);
+    }
 
     DPRINTF("copying device tree to 0x%lx[0x%x]\n", DEVTREE_ADDR, devtree_size);
     return install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR,
@@ -172,22 +187,35 @@ out:
 }
 
 static unsigned long create_start_info(
-       start_info_t *start_info,
+       void *devtree, start_info_t *start_info,
         unsigned int console_evtchn, unsigned int store_evtchn,
        unsigned long nr_pages, unsigned long rma_pages)
 {
     unsigned long start_info_addr;
+    uint64_t rma_top;
+    int rc;
 
     memset(start_info, 0, sizeof(*start_info));
-    snprintf(start_info->magic, sizeof(start_info->magic), "xen-%d.%d-powerpc64HV", 3, 0);
+    snprintf(start_info->magic, sizeof(start_info->magic),
+             "xen-%d.%d-powerpc64HV", 3, 0);
+
+    rma_top = rma_pages << PAGE_SHIFT;
+    DPRINTF("RMA top = 0x%"PRIX64"\n", rma_top);
 
     start_info->nr_pages = nr_pages;
-    start_info->shared_info = (nr_pages - 1) << PAGE_SHIFT;
-    start_info->store_mfn = start_info->nr_pages - 2;
+    start_info->shared_info = rma_top - PAGE_SIZE;
+    start_info->store_mfn = (rma_top >> PAGE_SHIFT) - 2;
     start_info->store_evtchn = store_evtchn;
-    start_info->console.domU.mfn = start_info->nr_pages - 3;
+    start_info->console.domU.mfn = (rma_top >> PAGE_SHIFT) - 3;
     start_info->console.domU.evtchn = console_evtchn;
-    start_info_addr = (start_info->nr_pages - 4) << PAGE_SHIFT;
+    start_info_addr = rma_top - 4*PAGE_SIZE;
+
+    rc = ft_set_rsvmap(devtree, 0, start_info_addr, 4*PAGE_SIZE);
+    if (rc < 0) {
+        DPRINTF("couldn't set start_info reservation\n");
+        return ~0UL;
+    }
+
 
     return start_info_addr;
 }
@@ -201,6 +229,7 @@ static void free_page_array(xen_pfn_t *page_array)
 
 int xc_linux_build(int xc_handle,
                    uint32_t domid,
+                   unsigned int mem_mb,
                    const char *image_name,
                    const char *initrd_name,
                    const char *cmdline,
@@ -226,8 +255,7 @@ int xc_linux_build(int xc_handle,
 
     DPRINTF("%s\n", __func__);
 
-    DPRINTF("xc_get_tot_pages\n");
-    nr_pages = xc_get_tot_pages(xc_handle, domid);
+    nr_pages = mem_mb << (20 - PAGE_SHIFT);
     DPRINTF("nr_pages 0x%lx\n", nr_pages);
 
     rma_pages = get_rma_pages(devtree);
@@ -258,7 +286,7 @@ int xc_linux_build(int xc_handle,
     }
 
     /* start_info stuff: about to be removed  */
-    start_info_addr = create_start_info(&start_info, console_evtchn,
+    start_info_addr = create_start_info(devtree, &start_info, console_evtchn,
                                         store_evtchn, nr_pages, rma_pages);
     *console_mfn = page_array[start_info.console.domU.mfn];
     *store_mfn = page_array[start_info.store_mfn];
index 1d5bc7e0539b2f04fe3ce9d5535c4fd3b1139cd8..c26b520670af9c70cdd42a573f15c582a5942e2b 100644 (file)
@@ -230,6 +230,7 @@ static void free_page_array(xen_pfn_t *page_array)
 
 int xc_prose_build(int xc_handle,
                    uint32_t domid,
+                   unsigned int mem_mb,
                    const char *image_name,
                    const char *initrd_name,
                    const char *cmdline,
@@ -257,8 +258,7 @@ int xc_prose_build(int xc_handle,
 
     DPRINTF("cmdline=%s\n", cmdline);
 
-    DPRINTF("xc_get_tot_pages\n");
-    nr_pages = xc_get_tot_pages(xc_handle, domid);
+    nr_pages = mem_mb << (20 - PAGE_SHIFT);
     DPRINTF("nr_pages 0x%lx\n", nr_pages);
 
     rma_pages = get_rma_pages(devtree);
index c646d18ea8c9cf0a020dca133a4040ccaedfffc3..c347aeebf1755fd291d4ada9df48c3348873573f 100644 (file)
@@ -439,6 +439,10 @@ int xc_domain_memory_populate_physmap(int xc_handle,
                                       unsigned int address_bits,
                                       xen_pfn_t *extent_start);
 
+int xc_alloc_real_mode_area(int xc_handle,
+                            uint32_t domid,
+                            unsigned int log);
+
 int xc_domain_ioport_permission(int xc_handle,
                                 uint32_t domid,
                                 uint32_t first_port,
index 4637eefb86448651f2740088c9dbf64484125e11..cf5f370cc8d8aa413256f2341e87b5dba2050787 100644 (file)
@@ -124,6 +124,7 @@ int xc_get_hvm_param(
 
 int xc_prose_build(int xc_handle,
                    uint32_t domid,
+                   unsigned int mem_mb,
                    const char *image_name,
                    const char *ramdisk_name,
                    const char *cmdline,
index 5b348a6ee13e48f481f53996c01ad2b2af8abfec..59bdcdc4a51ec1e8d153d5414cc1db8e1ccbc790 100644 (file)
@@ -809,6 +809,28 @@ static PyObject *pyxc_domain_memory_increase_reservation(XcObject *self,
     return zero;
 }
 
+#ifdef __powerpc__
+static PyObject *pyxc_alloc_real_mode_area(XcObject *self,
+                                           PyObject *args,
+                                           PyObject *kwds)
+{
+    uint32_t dom;
+    unsigned int log;
+
+    static char *kwd_list[] = { "dom", "log", NULL };
+
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list, 
+                                      &dom, &log) )
+        return NULL;
+
+    if ( xc_alloc_real_mode_area(self->xc_handle, dom, log) )
+        return PyErr_SetFromErrno(xc_error);
+
+    Py_INCREF(zero);
+    return zero;
+}
+#endif
+
 static PyObject *pyxc_domain_ioport_permission(XcObject *self,
                                                PyObject *args,
                                                PyObject *kwds)
@@ -1185,6 +1207,16 @@ static PyMethodDef pyxc_methods[] = {
       " mem_kb [long]: .\n"
       "Returns: [int] 0 on success; -1 on error.\n" },
 
+#ifdef __powerpc__
+    { "arch_alloc_real_mode_area", 
+      (PyCFunction)pyxc_alloc_real_mode_area, 
+      METH_VARARGS | METH_KEYWORDS, "\n"
+      "Allocate a domain's real mode area.\n"
+      " dom [int]: Identifier of domain.\n"
+      " log [int]: Specifies the area's size.\n"
+      "Returns: [int] 0 on success; -1 on error.\n" },
+#endif
+
     { "domain_ioport_permission",
       (PyCFunction)pyxc_domain_ioport_permission,
       METH_VARARGS | METH_KEYWORDS, "\n"
index 37e457513d9028c818504a7dc44e7d90d07683fd..deddfcb0a30c776c1019951fda86b3e382b0a3c8 100644 (file)
@@ -22,6 +22,10 @@ import sys
 import struct
 import stat
 import re
+import glob
+import math
+
+_host_devtree_root = '/proc/device-tree'
 
 _OF_DT_HEADER = int("d00dfeed", 16) # avoid signed/unsigned FutureWarning
 _OF_DT_BEGIN_NODE = 0x1
@@ -33,8 +37,10 @@ def _bincat(seq, separator=''):
     '''Concatenate the contents of seq into a bytestream.'''
     strs = []
     for item in seq:
-        if type(item) == type(0):
+        if isinstance(item, int):
             strs.append(struct.pack(">I", item))
+        elif isinstance(item, long):
+            strs.append(struct.pack(">Q", item))
         else:
             try:
                 strs.append(item.to_bin())
@@ -231,38 +237,51 @@ class Tree(_Node):
         header.totalsize = len(payload) + _alignup(len(header.to_bin()), 8)
         return _pad(header.to_bin(), 8) + payload
 
-_host_devtree_root = '/proc/device-tree'
-def _getprop(propname):
-    '''Extract a property from the system's device tree.'''
-    f = file(os.path.join(_host_devtree_root, propname), 'r')
+def _readfile(fullpath):
+    '''Return full contents of a file.'''
+    f = file(fullpath, 'r')
     data = f.read()
     f.close()
     return data
 
+def _find_first_cpu(dirpath):
+    '''Find the first node of type 'cpu' in a directory tree.'''
+    cpulist = glob.glob(os.path.join(dirpath, 'cpus', '*'))
+    for node in cpulist:
+        try:
+            data = _readfile(os.path.join(node, 'device_type'))
+        except IOError:
+            continue
+        if 'cpu' in data:
+            return node
+    raise IOError("couldn't find any CPU nodes under " + dirpath)
+
 def _copynode(node, dirpath, propfilter):
-    '''Extract all properties from a node in the system's device tree.'''
+    '''Copy all properties and children nodes from a directory tree.'''
     dirents = os.listdir(dirpath)
     for dirent in dirents:
         fullpath = os.path.join(dirpath, dirent)
         st = os.lstat(fullpath)
         if stat.S_ISDIR(st.st_mode):
             child = node.addnode(dirent)
-            _copytree(child, fullpath, propfilter)
+            _copynode(child, fullpath, propfilter)
         elif stat.S_ISREG(st.st_mode) and propfilter(fullpath):
-            node.addprop(dirent, _getprop(fullpath))
-
-def _copytree(node, dirpath, propfilter):
-    path = os.path.join(_host_devtree_root, dirpath)
-    _copynode(node, path, propfilter)
+            node.addprop(dirent, _readfile(fullpath))
 
 def build(imghandler):
     '''Construct a device tree by combining the domain's configuration and
     the host's device tree.'''
     root = Tree()
 
-    # 4 pages: start_info, console, store, shared_info
+    # 1st reseravtion entry used for start_info, console, store, shared_info
     root.reserve(0x3ffc000, 0x4000)
 
+    # 2nd reservation enrty used for initrd, later on when we load the
+    # initrd we may fill this in with zeroes which signifies the end
+    # of the reservation map.  So as to avoid adding a zero map now we
+    # put some bogus yet sensible numbers here.
+    root.reserve(0x1000000, 0x1000)
+
     root.addprop('device_type', 'chrp-but-not-really\0')
     root.addprop('#size-cells', 2)
     root.addprop('#address-cells', 2)
@@ -270,35 +289,52 @@ def build(imghandler):
     root.addprop('compatible', 'Momentum,Maple\0')
 
     xen = root.addnode('xen')
-    xen.addprop('start-info', 0, 0x3ffc000, 0, 0x1000)
+    xen.addprop('start-info', long(0x3ffc000), long(0x1000))
     xen.addprop('version', 'Xen-3.0-unstable\0')
-    xen.addprop('reg', 0, imghandler.vm.domid, 0, 0)
+    xen.addprop('reg', long(imghandler.vm.domid), long(0))
     xen.addprop('domain-name', imghandler.vm.getName() + '\0')
     xencons = xen.addnode('console')
     xencons.addprop('interrupts', 1, 0)
 
-    # XXX split out RMA node
-    mem = root.addnode('memory@0')
+    # add memory nodes
     totalmem = imghandler.vm.getMemoryTarget() * 1024
-    mem.addprop('reg', 0, 0, 0, totalmem)
-    mem.addprop('device_type', 'memory\0')
-
+    rma_log = 26 ### imghandler.vm.info.get('powerpc_rma_log')
+    rma_bytes = 1 << rma_log
+
+    # RMA node
+    rma = root.addnode('memory@0')
+    rma.addprop('reg', long(0), long(rma_bytes))
+    rma.addprop('device_type', 'memory\0')
+
+    # all the rest in a single node
+    remaining = totalmem - rma_bytes
+    if remaining > 0:
+        mem = root.addnode('memory@1')
+        mem.addprop('reg', long(rma_bytes), long(remaining))
+        mem.addprop('device_type', 'memory\0')
+
+    # add CPU nodes
     cpus = root.addnode('cpus')
     cpus.addprop('smp-enabled')
     cpus.addprop('#size-cells', 0)
     cpus.addprop('#address-cells', 1)
 
     # Copy all properties the system firmware gave us, except for 'linux,'
-    # properties, from 'cpus/@0', once for every vcpu. Hopefully all cpus are
-    # identical...
+    # properties, from the first CPU node in the device tree. Do this once for
+    # every vcpu. Hopefully all cpus are identical...
     cpu0 = None
+    cpu0path = _find_first_cpu(_host_devtree_root)
     def _nolinuxprops(fullpath):
         return not os.path.basename(fullpath).startswith('linux,')
     for i in range(imghandler.vm.getVCpuCount()):
-        cpu = cpus.addnode('PowerPC,970@0')
-        _copytree(cpu, 'cpus/PowerPC,970@0', _nolinuxprops)
-        # and then overwrite what we need to
-        pft_size = imghandler.vm.info.get('pft-size', 0x14)
+        # create new node and copy all properties
+        cpu = cpus.addnode('PowerPC,970@%d' % i)
+        _copynode(cpu, cpu0path, _nolinuxprops)
+
+        # overwrite what we need to
+        shadow_mb = imghandler.vm.info.get('shadow_memory', 1)
+        shadow_mb_log = int(math.log(shadow_mb, 2))
+        pft_size = shadow_mb_log + 20
         cpu.setprop('ibm,pft-size', 0, pft_size)
 
         # set default CPU
@@ -307,13 +343,13 @@ def build(imghandler):
 
     chosen = root.addnode('chosen')
     chosen.addprop('cpu', cpu0.get_phandle())
-    chosen.addprop('memory', mem.get_phandle())
+    chosen.addprop('memory', rma.get_phandle())
     chosen.addprop('linux,stdout-path', '/xen/console\0')
     chosen.addprop('interrupt-controller', xen.get_phandle())
     chosen.addprop('bootargs', imghandler.cmdline + '\0')
     # xc_linux_load.c will overwrite these 64-bit properties later
-    chosen.addprop('linux,initrd-start', 0, 0)
-    chosen.addprop('linux,initrd-end', 0, 0)
+    chosen.addprop('linux,initrd-start', long(0))
+    chosen.addprop('linux,initrd-end', long(0))
 
     if 1:
         f = file('/tmp/domU.dtb', 'w')
index 8f59f4b4b11ce4223fc306a8f50d61a8cda84ce3..12621a8dfbb329f01731045cd5c7e603b0149a15 100644 (file)
@@ -246,6 +246,15 @@ class PPC_LinuxImageHandler(LinuxImageHandler):
                               features       = self.vm.getFeatures(),
                               arch_args      = devtree.to_bin())
 
+    def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
+        """@param shadow_mem_kb The configured shadow memory, in KiB.
+        @param maxmem_kb The configured maxmem, in KiB.
+        @return The corresponding required amount of shadow memory, also in
+        KiB.
+        PowerPC currently uses "shadow memory" to refer to the hash table."""
+        return max(maxmem_kb / 64, shadow_mem_kb)
+
+
 class PPC_ProseImageHandler(LinuxImageHandler):
 
     ostype = "prose"
@@ -273,6 +282,7 @@ class PPC_ProseImageHandler(LinuxImageHandler):
         devtree = FlatDeviceTree.build(self)
 
         return xc.prose_build(dom            = self.vm.getDomid(),
+                              memsize        = mem_mb,
                               image          = self.kernel,
                               store_evtchn   = store_evtchn,
                               console_evtchn = console_evtchn,
index d828f0a4b404f9b8993b4335600eb3a79dd82b81..65ee7c2aec951b771a34a2d1639ef30124eebcdc 100644 (file)
@@ -27,6 +27,7 @@ obj-y += memory.o
 obj-y += mm.o
 obj-y += mpic.o
 obj-y += mpic_init.o
+obj-y += numa.o
 obj-y += of-devtree.o
 obj-y += of-devwalk.o
 obj-y += ofd_fixup.o
@@ -36,6 +37,7 @@ obj-y += rtas.o
 obj-y += setup.o
 obj-y += shadow.o
 obj-y += smp.o
+obj-y += smpboot.o
 obj-y += smp-tbsync.o
 obj-y += sysctl.o
 obj-y += time.o
@@ -73,6 +75,7 @@ firmware_image.bin: firmware
 #
 irq.o: ../x86/irq.c
 physdev.o: ../x86/physdev.c
+numa.o: ../x86/numa.c
 
 HDRS += $(wildcard *.h)
 
index 31a594d03cea1ee6360b0b1ad9c6bc1a73b50c8e..45ed9599452fd86bd96888356b140ac07410fdb3 100644 (file)
@@ -105,15 +105,15 @@ void arch_domain_destroy(struct domain *d)
 
 static void machine_fail(const char *s)
 {
-    printf("%s failed, manual powercycle required!\n", s);
+    printk("%s failed, manual powercycle required!\n", s);
     for (;;)
         sleep();
 }
-
 void machine_halt(void)
 {
+    printk("machine_halt called: spinning....\n");
     console_start_sync();
-    printf("%s called\n", __func__);
+    printk("%s called\n", __func__);
     rtas_halt();
 
     machine_fail(__func__);
@@ -121,8 +121,9 @@ void machine_halt(void)
 
 void machine_restart(char * __unused)
 {
+    printk("machine_restart called: spinning....\n");
     console_start_sync();
-    printf("%s called\n", __func__);
+    printk("%s called\n", __func__);
     rtas_reboot();
     machine_fail(__func__);
 }
index 44739acdae4e4d3dff0d4f5d3b40a9ba3525a05e..58b168c4fc245e58676d57d2c954db0eb58cee35 100644 (file)
@@ -20,6 +20,7 @@
  */
 #include <xen/sched.h>
 #include <xen/mm.h>
+#include <xen/numa.h>
 #include "of-devtree.h"
 #include "oftree.h"
 #include "rtas.h"
@@ -238,6 +239,9 @@ void memory_init(module_t *mod, int mcount)
     DBG("total_pages: 0x%016lx\n", total_pages);
 
     init_frametable();
+
+    numa_initmem_init(0, max_page);
+
     end_boot_allocator();
 
     /* Add memory between the beginning of the heap and the beginning
index 4a0493978d10a166531c996ce6983d367f16cd2a..2a9499825ab6fe9d75b16964819a5aa8fd1b0813 100644 (file)
@@ -284,21 +284,21 @@ extern void copy_page(void *dp, void *sp)
     }
 }
 
+/* XXX should probably replace with faster data structure */
 static uint add_extent(struct domain *d, struct page_info *pg, uint order)
 {
     struct page_extents *pe;
 
     pe = xmalloc(struct page_extents);
     if (pe == NULL)
-        return 0;
+        return -ENOMEM;
 
     pe->pg = pg;
     pe->order = order;
-    pe->pfn = page_to_mfn(pg);
 
     list_add_tail(&pe->pe_list, &d->arch.extent_list);
 
-    return pe->pfn;
+    return 0;
 }
 
 void free_extents(struct domain *d)
@@ -337,7 +337,7 @@ uint allocate_extents(struct domain *d, uint nrpages, uint rma_nrpages)
         if (pg == NULL)
             return total_nrpages;
 
-        if (add_extent(d, pg, ext_order) == 0) {
+        if (add_extent(d, pg, ext_order) < 0) {
             free_domheap_pages(pg, ext_order);
             return total_nrpages;
         }
@@ -390,6 +390,7 @@ int allocate_rma(struct domain *d, unsigned int order)
 
     return 0;
 }
+
 void free_rma_check(struct page_info *page)
 {
     if (test_bit(_PGC_page_RMA, &page->count_info) &&
@@ -397,7 +398,6 @@ void free_rma_check(struct page_info *page)
         panic("Attempt to free an RMA page: 0x%lx\n", page_to_mfn(page));
 }
 
-
 ulong pfn2mfn(struct domain *d, ulong pfn, int *type)
 {
     ulong rma_base_mfn = page_to_mfn(d->arch.rma_page);
@@ -415,8 +415,7 @@ ulong pfn2mfn(struct domain *d, ulong pfn, int *type)
         /* Its a grant table access */
         t = PFN_TYPE_GNTTAB;
         mfn = gnttab_shared_mfn(d, d->grant_table, (pfn - max_page));
-    } else if (test_bit(_DOMF_privileged, &d->domain_flags) &&
-               cpu_io_mfn(pfn)) {
+    } else if (d->is_privileged && cpu_io_mfn(pfn)) {
         t = PFN_TYPE_IO;
         mfn = pfn;
     } else {
@@ -424,14 +423,18 @@ ulong pfn2mfn(struct domain *d, ulong pfn, int *type)
             t = PFN_TYPE_RMA;
             mfn = pfn + rma_base_mfn;
         } else {
+            ulong cur_pfn = rma_size_mfn;
+
             list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
-                uint end_pfn = pe->pfn + (1 << pe->order);
+                uint pe_pages = 1UL << pe->order;
+                uint end_pfn = cur_pfn + pe_pages;
 
-                if (pfn >= pe->pfn && pfn < end_pfn) {
+                if (pfn >= cur_pfn && pfn < end_pfn) {
                     t = PFN_TYPE_LOGICAL;
-                    mfn = page_to_mfn(pe->pg) + (pfn - pe->pfn);
+                    mfn = page_to_mfn(pe->pg) + (pfn - cur_pfn);
                     break;
                 }
+                cur_pfn += pe_pages;
             }
         }
 #ifdef DEBUG
@@ -492,8 +495,7 @@ unsigned long mfn_to_gmfn(struct domain *d, unsigned long mfn)
         return max_page + (mfn - gnttab_mfn);
 
     /* IO? */
-    if (test_bit(_DOMF_privileged, &d->domain_flags) &&
-        cpu_io_mfn(mfn))
+    if (d->is_privileged && cpu_io_mfn(mfn))
         return mfn;
 
     rma_mfn = page_to_mfn(d->arch.rma_page);
@@ -530,3 +532,10 @@ void shadow_drop_references(
     struct domain *d, struct page_info *page)
 {
 }
+
+int arch_domain_add_extent(struct domain *d, struct page_info *page, int order)
+{
+    if (add_extent(d, page, order) < 0)
+        return -ENOMEM;
+    return 0;
+}
diff --git a/xen/arch/powerpc/numa.c b/xen/arch/powerpc/numa.c
new file mode 100644 (file)
index 0000000..623b0c1
--- /dev/null
@@ -0,0 +1 @@
+#include "../x86/numa.c"
index 6582938178f497de2d49609007b910a7805751ff..e2a77a6398733d7665755c20d95f783f063e973c 100644 (file)
@@ -68,6 +68,8 @@ static ofdn_t ofd_memory_node_create(
     reg.sz = size;
     ofd_prop_add(m, n, "reg", &reg, sizeof (reg));
 
+    printk("Dom0: %s: %016lx, %016lx\n", path, start, size);
+
     return n;
 }
 
@@ -86,17 +88,19 @@ static void ofd_memory_extent_nodes(void *m, struct domain *d)
     ulong size;
     ofdn_t n;
     struct page_extents *pe;
+    ulong cur_pfn = 1UL << d->arch.rma_order;
 
+    start = cur_pfn << PAGE_SHIFT;
+    size = 0;
     list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
 
-        start = pe->pfn << PAGE_SHIFT;
-        size = 1UL << (pe->order + PAGE_SHIFT);
-
-        n = ofd_memory_node_create(m, OFD_ROOT, "", memory, memory,
-                                    start, size);
-
-        BUG_ON(n <= 0);
+        size += 1UL << (pe->order + PAGE_SHIFT);
+        if (pe->order != cpu_extent_order())
+            panic("we don't handle this yet\n");
     }
+    n = ofd_memory_node_create(m, OFD_ROOT, "", memory, memory,
+                               start, size);
+    BUG_ON(n <= 0);
 }
 
 void ofd_memory_props(void *m, struct domain *d)
index 2b7390d25243ad707c9c7d0d7d0bc3f3c8b67011..1e95d4c879f480ebfb2fd8b75d6514baa298f4b6 100644 (file)
@@ -178,7 +178,7 @@ long pte_enter(ulong flags, ulong ptex, ulong vsid, ulong rpn)
         return H_Parameter;
     }
 
-    if (mtype == PFN_TYPE_IO &&!test_bit(_DOMF_privileged, &d->domain_flags)) {
+    if (mtype == PFN_TYPE_IO && !d->is_privileged) {
         /* only a privilaged dom can access outside IO space */
         DBG("%s: unprivileged access to physical page: 0x%lx\n",
             __func__, pfn);
index 5adefae616139775ba33d11bea9b270d3e40d181..9b8ad111bad1d51e69be0b51be51e64ba5a9e2d2 100644 (file)
@@ -193,8 +193,8 @@ void cpu_initialize(int cpuid)
     mtdec(timebase_freq);
     mthdec(timebase_freq);
 
-    /* FIXME Do not set the NAP and DPM bits in HID0 until we have had a
-     * chance to audit the safe halt and idle loop code. */
+    /* FIXME Do not set the NAP bit in HID0 until we have had a chance
+     * to audit the safe halt and idle loop code. */
     hid0.bits.nap = 0;      /* NAP */
     hid0.bits.dpm = 1;      /* Dynamic Power Management */
 
index aaceab164b73258cf351b77c7008a3b8acec2cc4..c22e6712bbf6f4c4f8860ff44da09a82c102a9c3 100644 (file)
@@ -35,6 +35,7 @@
 #include <xen/gdbstub.h>
 #include <xen/symbols.h>
 #include <xen/keyhandler.h>
+#include <xen/numa.h>
 #include <acm/acm_hooks.h>
 #include <public/version.h>
 #include <asm/mpic.h>
@@ -77,10 +78,7 @@ ulong oftree_len;
 ulong oftree_end;
 
 uint cpu_hard_id[NR_CPUS] __initdata;
-cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
-cpumask_t cpu_online_map; /* missing ifdef in schedule.c */
 cpumask_t cpu_present_map;
-cpumask_t cpu_possible_map;
 
 /* XXX get this from ISA node in device tree */
 char *vgabase;
@@ -210,6 +208,15 @@ void startup_cpu_idle_loop(void)
     reset_stack_and_jump(idle_loop);
 }
 
+/* The boot_pa is enough "parea" for the boot CPU to get thru
+ * initialization, it will ultimately get replaced later */
+static __init void init_boot_cpu(void)
+{
+    static struct processor_area boot_pa;
+    boot_pa.whoami = 0;
+    parea = &boot_pa;
+}    
+
 static void init_parea(int cpuid)
 {
     /* Be careful not to shadow the global variable.  */
@@ -250,6 +257,9 @@ static int kick_secondary_cpus(int maxcpus)
         /* wait for it */
         while (!cpu_online(cpuid))
             cpu_relax();
+
+        numa_set_node(cpuid, 0);
+        numa_add_cpu(cpuid);
     }
 
     return 0;
@@ -293,6 +303,9 @@ static void __init __start_xen(multiboot_info_t *mbi)
     if ((mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0))
         cmdline_parse(__va((ulong)mbi->cmdline));
 
+    /* we need to be able to identify this CPU early on */
+    init_boot_cpu();
+
     /* We initialise the serial devices very early so we can get debugging. */
     ns16550.io_base = 0x3f8;
     ns16550_init(0, &ns16550);
index ed09b18461f920b3095bea00390ccd5ee69bb479..64bc1c686c9ba12a38ec266f3e2dcb99f5727f44 100644 (file)
@@ -101,9 +101,6 @@ unsigned int shadow_set_allocation(struct domain *d,
 
     addr = htab_alloc(d, order);
 
-    printk("%s: ibm,fpt-size should be: 0x%x\n", __func__,
-           d->arch.htab.log_num_ptes + LOG_PTE_SIZE);
-
     if (addr == 0)
         return -ENOMEM;
 
diff --git a/xen/arch/powerpc/smpboot.c b/xen/arch/powerpc/smpboot.c
new file mode 100644 (file)
index 0000000..90dff38
--- /dev/null
@@ -0,0 +1,29 @@
+
+#include <xen/config.h>
+#include <xen/init.h>
+#include <xen/types.h>
+#include <xen/cpumask.h>
+#include <asm/cache.h>
+
+/* representing HT siblings of each logical CPU */
+cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
+EXPORT_SYMBOL(cpu_sibling_map);
+
+/* representing HT and core siblings of each logical CPU */
+cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
+EXPORT_SYMBOL(cpu_core_map);
+
+/* bitmap of online cpus */
+cpumask_t cpu_online_map __read_mostly;
+EXPORT_SYMBOL(cpu_online_map);
+
+
+#ifdef CONFIG_HOTPLUG_CPU
+cpumask_t cpu_possible_map = CPU_MASK_ALL;
+#else
+cpumask_t cpu_possible_map;
+#endif
+EXPORT_SYMBOL(cpu_possible_map);
+
+u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0xff };
+EXPORT_SYMBOL(x86_cpu_to_apicid);
index d7e33bcff042b2c1a5671ac095c16ff19b632d1f..4fb2546dcbfdcd782a432ac4f1946330ab428bd9 100644 (file)
  * Authors: Hollis Blanchard <hollisb@us.ibm.com>
  */
 
-#include <xen/config.h>
-#include <xen/mm.h>
 #include <xen/sched.h>
+#include <xen/lib.h>
 #include <asm/current.h>
-#include <asm/uaccess.h>
+#include <asm/page.h>
 #include <asm/debugger.h>
-#include <public/xen.h>
-#include <public/xencomm.h>
-
-#undef DEBUG
-#ifdef DEBUG
-static int xencomm_debug = 1; /* extremely verbose */
-#else
-#define xencomm_debug 0
-#endif
 
 /* XXX need to return error, not panic, if domain passed a bad pointer */
-static unsigned long paddr_to_maddr(unsigned long paddr)
+unsigned long paddr_to_maddr(unsigned long paddr)
 {
     struct vcpu *v = get_current();
     struct domain *d = v->domain;
@@ -58,208 +48,3 @@ static unsigned long paddr_to_maddr(unsigned long paddr)
 
     return pa;
 }
-
-/**
- * xencomm_copy_from_guest: Copy a block of data from domain space.
- * @to:   Machine address.
- * @from: Physical address to a xencomm buffer descriptor.
- * @n:    Number of bytes to copy.
- * @skip: Number of bytes from the start to skip.
- *
- * Copy data from domain to hypervisor.
- *
- * Returns number of bytes that could not be copied.
- * On success, this will be zero.
- */
-unsigned long
-xencomm_copy_from_guest(void *to, const void *from, unsigned int n,
-        unsigned int skip)
-{
-    struct xencomm_desc *desc;
-    unsigned int from_pos = 0;
-    unsigned int to_pos = 0;
-    unsigned int i = 0;
-
-    /* first we need to access the descriptor */
-    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)from);
-    if (desc == NULL)
-        return n;
-
-    if (desc->magic != XENCOMM_MAGIC) {
-        printk("%s: error: %p magic was 0x%x\n",
-               __func__, desc, desc->magic);
-        return n;
-    }
-
-    /* iterate through the descriptor, copying up to a page at a time */
-    while ((to_pos < n) && (i < desc->nr_addrs)) {
-        unsigned long src_paddr = desc->address[i];
-        unsigned int pgoffset;
-        unsigned int chunksz;
-        unsigned int chunk_skip;
-
-        if (src_paddr == XENCOMM_INVALID) {
-            i++;
-            continue;
-        }
-
-        pgoffset = src_paddr % PAGE_SIZE;
-        chunksz = PAGE_SIZE - pgoffset;
-
-        chunk_skip = min(chunksz, skip);
-        from_pos += chunk_skip;
-        chunksz -= chunk_skip;
-        skip -= chunk_skip;
-
-        if (skip == 0) {
-            unsigned long src_maddr;
-            unsigned long dest = (unsigned long)to + to_pos;
-            unsigned int bytes = min(chunksz, n - to_pos);
-
-            src_maddr = paddr_to_maddr(src_paddr + chunk_skip);
-            if (src_maddr == 0)
-                return n - to_pos;
-
-            if (xencomm_debug)
-                printk("%lx[%d] -> %lx\n", src_maddr, bytes, dest);
-            memcpy((void *)dest, (void *)src_maddr, bytes);
-            from_pos += bytes;
-            to_pos += bytes;
-        }
-
-        i++;
-    }
-
-    return n - to_pos;
-}
-
-/**
- * xencomm_copy_to_guest: Copy a block of data to domain space.
- * @to:     Physical address to xencomm buffer descriptor.
- * @from:   Machine address.
- * @n:      Number of bytes to copy.
- * @skip: Number of bytes from the start to skip.
- *
- * Copy data from hypervisor to domain.
- *
- * Returns number of bytes that could not be copied.
- * On success, this will be zero.
- */
-unsigned long
-xencomm_copy_to_guest(void *to, const void *from, unsigned int n,
-        unsigned int skip)
-{
-    struct xencomm_desc *desc;
-    unsigned int from_pos = 0;
-    unsigned int to_pos = 0;
-    unsigned int i = 0;
-
-    /* first we need to access the descriptor */
-    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)to);
-    if (desc == NULL)
-        return n;
-
-    if (desc->magic != XENCOMM_MAGIC) {
-        printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
-        return n;
-    }
-
-    /* iterate through the descriptor, copying up to a page at a time */
-    while ((from_pos < n) && (i < desc->nr_addrs)) {
-        unsigned long dest_paddr = desc->address[i];
-        unsigned int pgoffset;
-        unsigned int chunksz;
-        unsigned int chunk_skip;
-
-        if (dest_paddr == XENCOMM_INVALID) {
-            i++;
-            continue;
-        }
-
-        pgoffset = dest_paddr % PAGE_SIZE;
-        chunksz = PAGE_SIZE - pgoffset;
-
-        chunk_skip = min(chunksz, skip);
-        to_pos += chunk_skip;
-        chunksz -= chunk_skip;
-        skip -= chunk_skip;
-
-        if (skip == 0) {
-            unsigned long dest_maddr;
-            unsigned long source = (unsigned long)from + from_pos;
-            unsigned int bytes = min(chunksz, n - from_pos);
-
-            dest_maddr = paddr_to_maddr(dest_paddr + chunk_skip);
-            if (dest_maddr == 0)
-                return -1;
-
-            if (xencomm_debug)
-                printk("%lx[%d] -> %lx\n", source, bytes, dest_maddr);
-            memcpy((void *)dest_maddr, (void *)source, bytes);
-            from_pos += bytes;
-            to_pos += bytes;
-        }
-
-        i++;
-    }
-
-    return n - from_pos;
-}
-
-/* Offset page addresses in 'handle' to skip 'bytes' bytes. Set completely
- * exhausted pages to XENCOMM_INVALID. */
-int xencomm_add_offset(void *handle, unsigned int bytes)
-{
-    struct xencomm_desc *desc;
-    int i = 0;
-
-    /* first we need to access the descriptor */
-    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)handle);
-    if (desc == NULL)
-        return -1;
-
-    if (desc->magic != XENCOMM_MAGIC) {
-        printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
-        return -1;
-    }
-
-    /* iterate through the descriptor incrementing addresses */
-    while ((bytes > 0) && (i < desc->nr_addrs)) {
-        unsigned long dest_paddr = desc->address[i];
-        unsigned int pgoffset;
-        unsigned int chunksz;
-        unsigned int chunk_skip;
-
-        if (dest_paddr == XENCOMM_INVALID) {
-            i++;
-            continue;
-        }
-
-        pgoffset = dest_paddr % PAGE_SIZE;
-        chunksz = PAGE_SIZE - pgoffset;
-
-        chunk_skip = min(chunksz, bytes);
-        if (chunk_skip == chunksz) {
-            /* exhausted this page */
-            desc->address[i] = XENCOMM_INVALID;
-        } else {
-            desc->address[i] += chunk_skip;
-        }
-        bytes -= chunk_skip;
-
-       i++;
-    }
-    return 0;
-}
-
-int xencomm_handle_is_null(void *ptr)
-{
-    struct xencomm_desc *desc;
-
-    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)ptr);
-    if (desc == NULL)
-        return 1;
-
-    return (desc->nr_addrs == 0);
-}
-
index 770c4b376ff6c5bb07157d50ecf5d5e654ce2721..3cb9eb78557e711f2bc41f47031343c13897a6c9 100644 (file)
@@ -31,5 +31,7 @@ obj-$(perfc)       += perfc.o
 obj-$(crash_debug) += gdbstub.o
 obj-$(xenoprof)    += xenoprof.o
 
+obj-$(CONFIG_XENCOMM) += xencomm.o
+
 # Object file contains changeset and compiler information.
 version.o: $(BASEDIR)/include/xen/compile.h
diff --git a/xen/common/xencomm.c b/xen/common/xencomm.c
new file mode 100644 (file)
index 0000000..f33c753
--- /dev/null
@@ -0,0 +1,316 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright (C) IBM Corp. 2006
+ *
+ * Authors: Hollis Blanchard <hollisb@us.ibm.com>
+ *          Tristan Gingold <tristan.gingold@bull.net>
+ */
+
+#include <xen/config.h>
+#include <xen/mm.h>
+#include <xen/sched.h>
+#include <xen/xencomm.h>
+#include <public/xen.h>
+#include <public/xencomm.h>
+
+
+#undef DEBUG
+#ifdef DEBUG
+static int xencomm_debug = 1; /* extremely verbose */
+#else
+#define xencomm_debug 0
+#endif
+
+static unsigned long
+xencomm_inline_from_guest(void *to, const void *from, unsigned int n,
+        unsigned int skip)
+{
+    unsigned long src_paddr = xencomm_inline_addr(from);
+
+    src_paddr += skip;
+
+    while (n > 0) {
+        unsigned int chunksz;
+        unsigned long src_maddr;
+        unsigned int bytes;
+
+        chunksz = PAGE_SIZE - (src_paddr % PAGE_SIZE);
+
+        bytes = min(chunksz, n);
+
+        src_maddr = paddr_to_maddr(src_paddr);
+        if (xencomm_debug)
+            printk("%lx[%d] -> %lx\n", src_maddr, bytes, (unsigned long)to);
+        memcpy(to, (void *)src_maddr, bytes);
+        src_paddr += bytes;
+        to += bytes;
+        n -= bytes;
+    }
+
+    /* Always successful. */
+    return 0;
+}
+
+/**
+ * xencomm_copy_from_guest: Copy a block of data from domain space.
+ * @to:   Machine address.
+ * @from: Physical address to a xencomm buffer descriptor.
+ * @n:    Number of bytes to copy.
+ * @skip: Number of bytes from the start to skip.
+ *
+ * Copy data from domain to hypervisor.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ */
+unsigned long
+xencomm_copy_from_guest(void *to, const void *from, unsigned int n,
+        unsigned int skip)
+{
+    struct xencomm_desc *desc;
+    unsigned int from_pos = 0;
+    unsigned int to_pos = 0;
+    unsigned int i = 0;
+
+    if (xencomm_is_inline(from))
+        return xencomm_inline_from_guest(to, from, n, skip);
+
+    /* first we need to access the descriptor */
+    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)from);
+    if (desc == NULL)
+        return n;
+
+    if (desc->magic != XENCOMM_MAGIC) {
+        printk("%s: error: %p magic was 0x%x\n",
+               __func__, desc, desc->magic);
+        return n;
+    }
+
+    /* iterate through the descriptor, copying up to a page at a time */
+    while ((to_pos < n) && (i < desc->nr_addrs)) {
+        unsigned long src_paddr = desc->address[i];
+        unsigned int pgoffset;
+        unsigned int chunksz;
+        unsigned int chunk_skip;
+
+        if (src_paddr == XENCOMM_INVALID) {
+            i++;
+            continue;
+        }
+
+        pgoffset = src_paddr % PAGE_SIZE;
+        chunksz = PAGE_SIZE - pgoffset;
+
+        chunk_skip = min(chunksz, skip);
+        from_pos += chunk_skip;
+        chunksz -= chunk_skip;
+        skip -= chunk_skip;
+
+        if (skip == 0) {
+            unsigned long src_maddr;
+            unsigned long dest = (unsigned long)to + to_pos;
+            unsigned int bytes = min(chunksz, n - to_pos);
+
+            src_maddr = paddr_to_maddr(src_paddr + chunk_skip);
+            if (src_maddr == 0)
+                return n - to_pos;
+
+            if (xencomm_debug)
+                printk("%lx[%d] -> %lx\n", src_maddr, bytes, dest);
+            memcpy((void *)dest, (void *)src_maddr, bytes);
+            from_pos += bytes;
+            to_pos += bytes;
+        }
+
+        i++;
+    }
+
+    return n - to_pos;
+}
+
+static unsigned long
+xencomm_inline_to_guest(void *to, const void *from, unsigned int n,
+        unsigned int skip)
+{
+    unsigned long dest_paddr = xencomm_inline_addr(to);
+
+    dest_paddr += skip;
+
+    while (n > 0) {
+        unsigned int chunksz;
+        unsigned long dest_maddr;
+        unsigned int bytes;
+
+        chunksz = PAGE_SIZE - (dest_paddr % PAGE_SIZE);
+
+        bytes = min(chunksz, n);
+
+        dest_maddr = paddr_to_maddr(dest_paddr);
+        if (xencomm_debug)
+            printk("%lx[%d] -> %lx\n", (unsigned long)from, bytes, dest_maddr);
+        memcpy((void *)dest_maddr, (void *)from, bytes);
+        dest_paddr += bytes;
+        from += bytes;
+        n -= bytes;
+    }
+
+    /* Always successful.  */
+    return 0;
+}
+
+/**
+ * xencomm_copy_to_guest: Copy a block of data to domain space.
+ * @to:     Physical address to xencomm buffer descriptor.
+ * @from:   Machine address.
+ * @n:      Number of bytes to copy.
+ * @skip: Number of bytes from the start to skip.
+ *
+ * Copy data from hypervisor to domain.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ */
+unsigned long
+xencomm_copy_to_guest(void *to, const void *from, unsigned int n,
+        unsigned int skip)
+{
+    struct xencomm_desc *desc;
+    unsigned int from_pos = 0;
+    unsigned int to_pos = 0;
+    unsigned int i = 0;
+
+    if (xencomm_is_inline(to))
+        return xencomm_inline_to_guest(to, from, n, skip);
+
+    /* first we need to access the descriptor */
+    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)to);
+    if (desc == NULL)
+        return n;
+
+    if (desc->magic != XENCOMM_MAGIC) {
+        printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
+        return n;
+    }
+
+    /* iterate through the descriptor, copying up to a page at a time */
+    while ((from_pos < n) && (i < desc->nr_addrs)) {
+        unsigned long dest_paddr = desc->address[i];
+        unsigned int pgoffset;
+        unsigned int chunksz;
+        unsigned int chunk_skip;
+
+        if (dest_paddr == XENCOMM_INVALID) {
+            i++;
+            continue;
+        }
+
+        pgoffset = dest_paddr % PAGE_SIZE;
+        chunksz = PAGE_SIZE - pgoffset;
+
+        chunk_skip = min(chunksz, skip);
+        to_pos += chunk_skip;
+        chunksz -= chunk_skip;
+        skip -= chunk_skip;
+
+        if (skip == 0) {
+            unsigned long dest_maddr;
+            unsigned long source = (unsigned long)from + from_pos;
+            unsigned int bytes = min(chunksz, n - from_pos);
+
+            dest_maddr = paddr_to_maddr(dest_paddr + chunk_skip);
+            if (dest_maddr == 0)
+                return -1;
+
+            if (xencomm_debug)
+                printk("%lx[%d] -> %lx\n", source, bytes, dest_maddr);
+            memcpy((void *)dest_maddr, (void *)source, bytes);
+            from_pos += bytes;
+            to_pos += bytes;
+        }
+
+        i++;
+    }
+
+    return n - from_pos;
+}
+
+static int xencomm_inline_add_offset(void **handle, unsigned int bytes)
+{
+    *handle += bytes;
+    return 0;
+}
+
+/* Offset page addresses in 'handle' to skip 'bytes' bytes. Set completely
+ * exhausted pages to XENCOMM_INVALID. */
+int xencomm_add_offset(void **handle, unsigned int bytes)
+{
+    struct xencomm_desc *desc;
+    int i = 0;
+
+    if (xencomm_is_inline(*handle))
+        return xencomm_inline_add_offset(handle, bytes);
+
+    /* first we need to access the descriptor */
+    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)*handle);
+    if (desc == NULL)
+        return -1;
+
+    if (desc->magic != XENCOMM_MAGIC) {
+        printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic);
+        return -1;
+    }
+
+    /* iterate through the descriptor incrementing addresses */
+    while ((bytes > 0) && (i < desc->nr_addrs)) {
+        unsigned long dest_paddr = desc->address[i];
+        unsigned int pgoffset;
+        unsigned int chunksz;
+        unsigned int chunk_skip;
+
+        pgoffset = dest_paddr % PAGE_SIZE;
+        chunksz = PAGE_SIZE - pgoffset;
+
+        chunk_skip = min(chunksz, bytes);
+        if (chunk_skip == chunksz) {
+            /* exhausted this page */
+            desc->address[i] = XENCOMM_INVALID;
+        } else {
+            desc->address[i] += chunk_skip;
+        }
+        bytes -= chunk_skip;
+    }
+    return 0;
+}
+
+int xencomm_handle_is_null(void *handle)
+{
+    struct xencomm_desc *desc;
+    int i;
+
+    if (xencomm_is_inline(handle))
+        return xencomm_inline_addr(handle) == 0;
+
+    desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)handle);
+    if (desc == NULL)
+        return 1;
+
+    for (i = 0; i < desc->nr_addrs; i++)
+        if (desc->address[i] != XENCOMM_INVALID)
+            return 0;
+
+    return 1;
+}
+
diff --git a/xen/include/asm-powerpc/acpi.h b/xen/include/asm-powerpc/acpi.h
new file mode 100644 (file)
index 0000000..a5cbef4
--- /dev/null
@@ -0,0 +1,2 @@
+#define MAX_LOCAL_APIC 256
+
index f2df6d83cc659f950b281b283afc0d665a95186b..82d1138b6f0fc6121517aa3f4248df338a27ccd6 100644 (file)
@@ -50,6 +50,7 @@ extern char __bss_start[];
 #define CONFIG_GDB 1
 #define CONFIG_SMP 1
 #define CONFIG_PCI 1
+#define CONFIG_NUMA 1
 #define CONFIG_CMDLINE_SIZE 512
 #define NR_CPUS 16
 
index 4c7693e4371942fc6f300b5e899f822531da46f5..50f999c2813e7df656e824848e25ae9ff9025cac 100644 (file)
@@ -89,7 +89,7 @@ struct arch_vcpu {
     struct slb_entry slb_entries[NUM_SLB_ENTRIES];
 
     /* I/O-port access bitmap. */
-    u8 *iobmp;        /* Guest kernel virtual address of the bitmap. */
+    XEN_GUEST_HANDLE(uint8_t) iobmp; /* Guest kernel virtual address of the bitmap. */
     int iobmp_limit;  /* Number of ports represented in the bitmap.  */
     int iopl;         /* Current IOPL for this VCPU. */
 
index fcae9d5d31cbdaef89d5c9167be258d52e6a1c12..948d4507a1786deff7c6170a1261c1cfade18d89 100644 (file)
 #ifndef __PPC_GUEST_ACCESS_H__
 #define __PPC_GUEST_ACCESS_H__
 
-extern unsigned long xencomm_copy_to_guest(void *to, const void *from,
-        unsigned int len, unsigned int skip); 
-extern unsigned long xencomm_copy_from_guest(void *to, const void *from,
-        unsigned int len, unsigned int skip); 
-extern int xencomm_add_offset(void *handle, unsigned int bytes);
-extern int xencomm_handle_is_null(void *ptr);
-
-
-/* Is the guest handle a NULL reference? */
-#define guest_handle_is_null(hnd) \
-    ((hnd).p == NULL || xencomm_handle_is_null((hnd).p))
-
-/* Offset the given guest handle into the array it refers to. */
-#define guest_handle_add_offset(hnd, nr) ({         \
-    const typeof((hnd).p) _ptr = (hnd).p;           \
-    xencomm_add_offset(_ptr, nr * sizeof(*_ptr));   \
-})
-
-/* Cast a guest handle to the specified type of handle. */
-#define guest_handle_cast(hnd, type) ({         \
-    type *_x = (hnd).p;                         \
-    XEN_GUEST_HANDLE(type) _y; \
-    set_xen_guest_handle(_y, _x); \
-    _y; \
-})
-
-/* Since we run in real mode, we can safely access all addresses. That also
- * means our __routines are identical to our "normal" routines. */
-#define guest_handle_okay(hnd, nr) 1
-
-/*
- * Copy an array of objects to guest context via a guest handle.
- * Optionally specify an offset into the guest array.
- */
-#define copy_to_guest_offset(hnd, idx, ptr, nr) \
-    __copy_to_guest_offset(hnd, idx, ptr, nr)
-
-/* Copy sub-field of a structure to guest context via a guest handle. */
-#define copy_field_to_guest(hnd, ptr, field) \
-    __copy_field_to_guest(hnd, ptr, field)
-
-/*
- * Copy an array of objects from guest context via a guest handle.
- * Optionally specify an offset into the guest array.
- */
-#define copy_from_guest_offset(ptr, hnd, idx, nr) \
-    __copy_from_guest_offset(ptr, hnd, idx, nr)
-
-/* Copy sub-field of a structure from guest context via a guest handle. */
-#define copy_field_from_guest(ptr, hnd, field) \
-    __copy_field_from_guest(ptr, hnd, field)
-
-#define __copy_to_guest_offset(hnd, idx, ptr, nr) ({                \
-    const typeof(ptr) _x = (hnd).p;                                 \
-    const typeof(ptr) _y = (ptr);                                   \
-    xencomm_copy_to_guest(_x, _y, sizeof(*_x)*(nr), sizeof(*_x)*(idx)); \
-})
-
-#define __copy_field_to_guest(hnd, ptr, field) ({                   \
-    const int _off = offsetof(typeof(*ptr), field);                  \
-    const typeof(&(ptr)->field) _x = &(hnd).p->field;               \
-    const typeof(&(ptr)->field) _y = &(ptr)->field;                 \
-    xencomm_copy_to_guest(_x, _y, sizeof(*_x), sizeof(*_x)*(_off)); \
-})
-
-#define __copy_from_guest_offset(ptr, hnd, idx, nr) ({              \
-    const typeof(ptr) _x = (hnd).p;                                 \
-    const typeof(ptr) _y = (ptr);                                   \
-    xencomm_copy_from_guest(_y, _x, sizeof(*_x)*(nr), sizeof(*_x)*(idx));  \
-})
-
-#define __copy_field_from_guest(ptr, hnd, field) ({                 \
-    const int _off = offsetof(typeof(*ptr), field);                 \
-    const typeof(&(ptr)->field) _x = &(hnd).p->field;               \
-    const typeof(&(ptr)->field) _y = &(ptr)->field;                 \
-    xencomm_copy_to_guest(_y, _x, sizeof(*_x), sizeof(*_x)*(_off)); \
-})
+#include <xen/xencomm.h>
 
 #endif /* __PPC_GUEST_ACCESS_H__ */
index 78886bcc3894867664bc6347864fed7fe8b0aadc..1cb77b658f9a04f093abe4f649fc69ef15cf024c 100644 (file)
@@ -28,7 +28,7 @@
 #include <xen/mm.h>
 #include <asm/system.h>
 #include <asm/flushtlb.h>
-#include <asm/uaccess.h>
+#include <asm/page.h>
 #include <asm/debugger.h>
 
 #define memguard_guard_range(_p,_l)    ((void)0)
@@ -87,7 +87,6 @@ struct page_extents {
     /* page extent */
     struct page_info *pg;
     uint order;
-    ulong pfn;
 };
 
  /* The following page types are MUTUALLY EXCLUSIVE. */
@@ -273,72 +272,20 @@ extern int update_grant_va_mapping(unsigned long va,
                                    struct domain *,
                                    struct vcpu *);
 
-#define INVALID_MFN (~0UL)
-#define PFN_TYPE_NONE 0
-#define PFN_TYPE_RMA 1
-#define PFN_TYPE_LOGICAL 2
-#define PFN_TYPE_IO 3
-#define PFN_TYPE_FOREIGN 4
-
-extern ulong pfn2mfn(struct domain *d, ulong pfn, int *type);
-
 /* Arch-specific portion of memory_op hypercall. */
 long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg);
 
-/* XXX implement me? */
-#define set_gpfn_from_mfn(mfn, pfn) do { } while (0)
-/* XXX only used for debug print right now... */
-#define get_gpfn_from_mfn(mfn) (mfn)
-
-static inline unsigned long gmfn_to_mfn(struct domain *d, unsigned long gmfn)
-{
-    int mtype;
-    ulong mfn;
-    
-    mfn = pfn2mfn(d, gmfn, &mtype);
-    if (mfn != INVALID_MFN) {
-        switch (mtype) {
-        case PFN_TYPE_RMA:
-        case PFN_TYPE_LOGICAL:
-            break;
-        default:
-            WARN();
-            mfn = INVALID_MFN;
-            break;
-        }
-    }
-    return mfn;
-}
-
-#define mfn_to_gmfn(_d, mfn) (mfn)
-
 extern int allocate_rma(struct domain *d, unsigned int order_pages);
 extern uint allocate_extents(struct domain *d, uint nrpages, uint rma_nrpages);
 extern void free_extents(struct domain *d);
 
+extern int arch_domain_add_extent(struct domain *d, struct page_info *page,
+        int order);
+
 extern int steal_page(struct domain *d, struct page_info *page,
                         unsigned int memflags);
 
-static inline unsigned long gmfn_to_mfn(struct domain *d, unsigned long gmfn)
-{
-    int mtype;
-    ulong mfn;
-    
-    mfn = pfn2mfn(d, gmfn, &mtype);
-    if (mfn != INVALID_MFN) {
-        switch (mtype) {
-        case PFN_TYPE_RMA:
-        case PFN_TYPE_LOGICAL:
-            break;
-        default:
-            WARN();
-            mfn = INVALID_MFN;
-            break;
-        }
-    }
-    return mfn;
-}
-
-#define mfn_to_gmfn(_d, mfn) (mfn)
-
+/* XXX these just exist until we can stop #including x86 code */
+#define access_ok(addr,size) 1
+#define array_access_ok(addr,count,size) 1
 #endif
diff --git a/xen/include/asm-powerpc/numa.h b/xen/include/asm-powerpc/numa.h
new file mode 100644 (file)
index 0000000..1fa9f6c
--- /dev/null
@@ -0,0 +1,2 @@
+#include "../asm-x86/numa.h"
+extern void numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn);
index 61a757fb797e7be333f47c153c5dcbf417521a4f..f6508498581ad27b33d7720ebe9b7095f57c6197 100644 (file)
@@ -13,7 +13,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
- * Copyright (C) IBM Corp. 2005
+ * Copyright (C) IBM Corp. 2005, 2006
  *
  * Authors: Hollis Blanchard <hollisb@us.ibm.com>
  *          Jimi Xenidis <jimix@watson.ibm.com>
@@ -129,5 +129,6 @@ static inline int get_order_from_pages(unsigned long nr_pages)
 #define _PAGE_PAT      0x080UL
 #define _PAGE_PSE      0x080UL
 #define _PAGE_GLOBAL   0x100UL
+
 #endif  /* ! __ASSEMBLY__ */
 #endif
index 51b55f44fbbf80cdd0581be21eccf9a537bc9272..648501fbd13788790a5dff5bbf81a69ba24b7b37 100644 (file)
 #include <xen/cpumask.h>
 #include <xen/init.h>
 #include <asm/current.h>
+
+/* crap to make x86 "common code" happy */
+#define BAD_APICID 0xFFu
+extern u8 x86_cpu_to_apicid[];
+
+
 extern int smp_num_siblings;
 
 /* revisit when we support SMP */
index 8302c92d251899760276daa593c2daa99fde7da3..a6dc16c82e7f4ebf41ee852e22f1b8b75bbcc4f9 100644 (file)
@@ -72,13 +72,13 @@ cas_u32(volatile u32 *ptr, u32 oval, u32 nval)
 
 typedef struct {
     volatile u32 lock;
-       u16 recurse_cpu;
-       u16 recurse_cnt;
+    s16 recurse_cpu;
+    u16 recurse_cnt;
 } spinlock_t;
 
 #define __UNLOCKED (0U)
 #define __LOCKED (~__UNLOCKED)
-#define SPIN_LOCK_UNLOCKED /*(spinlock_t)*/ { __UNLOCKED }
+#define SPIN_LOCK_UNLOCKED /*(spinlock_t)*/ { __UNLOCKED, -1, 0 }
 static inline void spin_lock_init(spinlock_t *lock)
 {
     *lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
diff --git a/xen/include/xen/xencomm.h b/xen/include/xen/xencomm.h
new file mode 100644 (file)
index 0000000..e961cc6
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright (C) IBM Corp. 2006
+ *
+ * Authors: Hollis Blanchard <hollisb@us.ibm.com>
+ */
+
+#ifndef __XENCOMM_H__
+#define __XENCOMM_H__
+
+#include <public/xen.h>
+
+extern unsigned long xencomm_copy_to_guest(void *to, const void *from,
+        unsigned int len, unsigned int skip); 
+extern unsigned long xencomm_copy_from_guest(void *to, const void *from,
+        unsigned int len, unsigned int skip); 
+extern int xencomm_add_offset(void **handle, unsigned int bytes);
+extern int xencomm_handle_is_null(void *ptr);
+
+
+static inline int xencomm_is_inline(const void *handle)
+{
+    unsigned long addr = (unsigned long)handle;
+    return (addr & XENCOMM_INLINE_FLAG) == XENCOMM_INLINE_FLAG;
+}
+
+static inline unsigned long xencomm_inline_addr(const void *handle)
+{
+       return (unsigned long)handle & ~XENCOMM_INLINE_FLAG;
+}
+
+/* Is the guest handle a NULL reference? */
+#define guest_handle_is_null(hnd) \
+    ((hnd).p == NULL || xencomm_handle_is_null((hnd).p))
+
+/* Offset the given guest handle into the array it refers to. */
+#define guest_handle_add_offset(hnd, nr) ({         \
+    const typeof((hnd).p) _ptr;                     \
+    xencomm_add_offset((void **)&((hnd).p), nr * sizeof(*_ptr));   \
+})
+
+/* Cast a guest handle to the specified type of handle. */
+#define guest_handle_cast(hnd, type) ({         \
+    type *_x = (hnd).p;                         \
+    XEN_GUEST_HANDLE(type) _y; \
+    set_xen_guest_handle(_y, _x); \
+    _y; \
+})
+
+/* Since we run in real mode, we can safely access all addresses. That also
+ * means our __routines are identical to our "normal" routines. */
+#define guest_handle_okay(hnd, nr) 1
+
+/*
+ * Copy an array of objects to guest context via a guest handle.
+ * Optionally specify an offset into the guest array.
+ */
+#define copy_to_guest_offset(hnd, idx, ptr, nr) \
+    __copy_to_guest_offset(hnd, idx, ptr, nr)
+
+/* Copy sub-field of a structure to guest context via a guest handle. */
+#define copy_field_to_guest(hnd, ptr, field) \
+    __copy_field_to_guest(hnd, ptr, field)
+
+/*
+ * Copy an array of objects from guest context via a guest handle.
+ * Optionally specify an offset into the guest array.
+ */
+#define copy_from_guest_offset(ptr, hnd, idx, nr) \
+    __copy_from_guest_offset(ptr, hnd, idx, nr)
+
+/* Copy sub-field of a structure from guest context via a guest handle. */
+#define copy_field_from_guest(ptr, hnd, field) \
+    __copy_field_from_guest(ptr, hnd, field)
+
+#define __copy_to_guest_offset(hnd, idx, ptr, nr) ({                \
+    const typeof(ptr) _x = (hnd).p;                                 \
+    const typeof(ptr) _y = (ptr);                                   \
+    xencomm_copy_to_guest(_x, _y, sizeof(*_x)*(nr), sizeof(*_x)*(idx)); \
+})
+
+#define __copy_field_to_guest(hnd, ptr, field) ({                   \
+    const int _off = offsetof(typeof(*ptr), field);                  \
+    const typeof(&(ptr)->field) _x = &(hnd).p->field;               \
+    const typeof(&(ptr)->field) _y = &(ptr)->field;                 \
+    xencomm_copy_to_guest(_x, _y, sizeof(*_x), sizeof(*_x)*(_off)); \
+})
+
+#define __copy_from_guest_offset(ptr, hnd, idx, nr) ({              \
+    const typeof(ptr) _x = (hnd).p;                                 \
+    const typeof(ptr) _y = (ptr);                                   \
+    xencomm_copy_from_guest(_y, _x, sizeof(*_x)*(nr), sizeof(*_x)*(idx));  \
+})
+
+#define __copy_field_from_guest(ptr, hnd, field) ({                 \
+    const int _off = offsetof(typeof(*ptr), field);                 \
+    const typeof(&(ptr)->field) _x = &(hnd).p->field;               \
+    const typeof(&(ptr)->field) _y = &(ptr)->field;                 \
+    xencomm_copy_to_guest(_y, _x, sizeof(*_x), sizeof(*_x)*(_off)); \
+})
+
+#endif /* __XENCOMM_H__ */